package com.termux.ide;


import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import com.termux.*;
import android.widget.*;
import com.termux.app.TermuxActivity;
import com.jsdroid.fileview.FileView;
import android.view.View.*;
import android.transition.*;
import android.view.animation.*;
import com.termux.terminal.TerminalSession;
import com.jsdroid.editor.widget.FileTabView;
import com.jsdroid.editor.widget.FileTabView.*;
import com.jsdroid.editor.widget.*;
import java.io.*;
import com.jsdroid.editor.parser.*;
import android.text.*;
import android.app.*;
import android.content.*;
import org.apache.commons.io.*;
import android.view.inputmethod.*;
import android.view.*;
import java.util.*;
import com.termux.util.*;
import android.graphics.*;
import com.alibaba.fastjson.*;
import com.termux.view.BasePropView;
import com.termux.view.PropListView;
import com.qmuiteam.qmui.util.*;
import android.support.v7.widget.*;
import com.termux.commons.*;
import com.termux.project.*;

public class MainActivity extends TermuxActivity implements FileTabView.FileTabListener
{

	public FileView getFileView()
	{
		// TODO: Implement this method
		return fileView;
	}

	public void showFileTree()
	{
		// TODO: Implement this method
		drawer.openDrawer(GravityCompat.START);
	}

	public void addExecSession(String execFile, String[] args, String cwd, String sessionName)
    {
		if (mTermService.getSessions().size() >= MAX_SESSIONS) {
            new AlertDialog.Builder(this).setTitle(R.string.max_terminals_reached_title).setMessage(R.string.max_terminals_reached_message)
                .setPositiveButton(android.R.string.ok, null).show();
        } else {

            TerminalSession newSession = mTermService.createTermSession(execFile, args, cwd, false);
            if (sessionName != null) {
                newSession.mSessionName = sessionName;
            }
            if (viewSwitch.getDisplayedChild() == 0)
		    {
				viewSwitch.setDisplayedChild(1);
				mTerminalView.requestFocus();

            }
            switchToSession(newSession);
            getDrawer().closeDrawers();
        }
    }

	@Override
	public void onCloseTab(FileTabView.FileTab fileTab)
	{
		// TODO: Implement this method
	}

	@Override
	public void onSelectTab(FileTabView.FileTab fileTab)
	{
		// TODO: Implement this method
	}

	@Override
	public void onOpenTab(FileTabView.FileTab fileTab)
	{
		// TODO: Implement this method
	}
	/**
     * 关闭输入法
     *
     * @param view
     */
    private void closeInputMethod(View view) {
        //关闭输入法
        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(view.getWindowToken()
												   , InputMethodManager.HIDE_NOT_ALWAYS);
	}
	public class CustomerTab extends FileTabView.FileTab {
        private File file;

        public CustomerTab(File file) {
            super(file);
            this.file = file;
        }

        public File getFile() {
            return file;
        }

        @Override
        public int getDefaultColor() {
            return Colors.tabDefaultColor;
        }

        @Override
        public int getSelectColor() {
            return Colors.tabSelectColor;
        }

        @Override
        public int getDefaultTextColor() {

            return Colors.tabDefaultTextColor;
        }

        @Override
        public int getSelectTextColor() {
            return Colors.tabSelectTextColor;
        }

        @Override
        public int getImage() {
            return com.jsdroid.editor.R.drawable.ic_file;
        }

        @Override
        public String getText() {
            return file.getName();
        }

        @Override
        public void save() {

        }

        @Override
        public void onSelected(FileTabView fileTabView) {
            editorContentView.removeAllViews();
            editorContentView.addView(getContentView());
            editToolView.setVisibility(View.GONE);
        }

        @Override
        public void onClosed(FileTabView fileTabView) {
            editorContentView.removeView(getContentView());
            //检测是否没有打开文件
            checkNotOpen();
        }

        public View getContentView() {
            return new View(MainActivity.this);
        }
    }
	public class EditTab extends FileTabView.FileTab implements TextWatcher {
        CodeEditPane codeEditPane;
        boolean changed;

		
        public EditTab(File file) throws Exception {
            super(file);
            if (file.length() > 100_0000) {
                throw new Exception("文件太大！");
            }
            this.file = file;
            codeEditPane = new CodeEditPane(MainActivity.this);
            codeEditPane.setParser(ParserFactory.getParser(file));
            codeEditPane.openFile(file);
            codeEditPane.getCodeEditText().setTextWatcher(this);
        }

        @Override
        public int getDefaultColor() {
            return Colors.tabDefaultColor;
        }

        @Override
        public int getSelectColor() {
            return Colors.tabSelectColor;
        }

        @Override
        public int getDefaultTextColor() {

            return Colors.tabDefaultTextColor;
        }

        @Override
        public int getSelectTextColor() {
            return Colors.tabSelectTextColor;
        }

        @Override
        public int getImage() {
            return com.jsdroid.editor.R.drawable.ic_file;
        }

        @Override
        public String getText() {
            return file.getName();
        }

        private void openFile() {
            //打开编辑界面
            codeEditPane.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            editorContentView.removeAllViews();
            editorContentView.addView(codeEditPane);
            codeEditText = codeEditPane.getCodeText();
            //绑定工具栏
            editToolView.setCodeEditText(codeEditText);
            editToolView.setVisibility(View.VISIBLE);
            codeEditText.requestFocus();
        }

        @Override
        public void onSelected(FileTabView fileTabView) {
            openFile();
        }

        @Override
        public void onClosed(FileTabView fileTabView) {
            closeInputMethod(codeEditPane.getCodeText());
            codeEditPane.getCodeText().closeTips();
            editorContentView.removeView(codeEditPane);
            //判断是否需要保存文件
            if (changed) {
                new AlertDialog.Builder(MainActivity.this).setTitle("提示").setMessage("是否保存文件" + file.getName() + "？").setNegativeButton("不保存", new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
						}
					}).setPositiveButton("保存", new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
							save();
						}
					}).setCancelable(false).create().show();
            }
            //检测是否没有打开文件
            checkNotOpen();
        }

        @Override
        public void save() {
            if (changed) {
                changed = false;
                setTitle(file.getName());
                try {
                    FileUtils.writeStringToFile(file, codeEditPane.getCodeText().getText().toString(), "utf-8");
                } catch (IOException e) {
                }
            }
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            changed = true;
            setTitle(file.getName() + "*");
        }
    }
	
	public void addFileType(FileType fileType) {
        if (fileTypes == null) {
            fileTypes = new ArrayList<>();
        }
        if (!fileTypes.contains(fileType)) {
            fileTypes.add(fileType);
        }
    }
	
	class XmlTab extends CustomerTab {

        LinearLayout designView = new LinearLayout(MainActivity.this);

        public XmlTab(File file) {
            super(file);
        }

        @Override
        public View getContentView() {
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            designView.setLayoutParams(params);
            designView.setBackgroundColor(Color.WHITE);
            return designView;
        }
    }

    class XmlFileType implements FileType {

        @Override
        public boolean forFile(File file) {

            return file.getName().endsWith(".xml");
        }

        @Override
        public FileTabView.FileTab open(File file) {
            return new XmlTab(file);
        }
    }

    class ImageTab extends CustomerTab {
        ImageView imageView;
        LinearLayout contentView;

        public ImageTab(File file) {
            super(file);
            contentView = new LinearLayout(MainActivity.this);
            contentView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

            imageView = new ImageView(MainActivity.this);
            contentView.addView(imageView);
            contentView.setGravity(Gravity.CENTER);

        }

        @Override
        public View getContentView() {
            imageView.setImageBitmap(BitmapFactory.decodeFile(getFile().getPath()));
            contentView.setBackgroundColor(Colors.tabSelectColor);
            return contentView;
        }
    }

    class ImageFileType implements FileType {

        @Override
        public boolean forFile(File file) {
            String path = file.getPath();
            if (path.endsWith(".jpg")) {
                return true;
            }
            if (path.endsWith(".webp")) {
                return true;
            }
            if (path.endsWith(".png")) {
                return true;
            }
            return false;
        }

        @Override
        public FileTabView.FileTab open(File file) {
            return new ImageTab(file);
        }
    }


    class ConfigTab extends CustomerTab implements PropListView.OnPropChangedListener {
        PropListView propListView;
        LinearLayout contentView;
        ImageView logoView;
        JSONObject jsonObject;

        @Override
        public String getText() {
            return "项目属性";
        }

        public ConfigTab(File file) {
            super(file);
            jsonObject = JSON.parseObject(FileUtil.read(file));
            contentView = new LinearLayout(MainActivity.this);
            contentView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            propListView = new PropListView(MainActivity.this);
            propListView.addPropView("pkg", "包名", jsonObject.getString("pkg"), BasePropView.class);
            propListView.addPropView("name", "名称", jsonObject.getString("name"));
            propListView.addPropView("note", "介绍", jsonObject.getString("note"));
            propListView.addPropView("version", "版本", jsonObject.getString("version"));
            propListView.addPropView("libs","链接库",jsonObject.getString("libs"));
			propListView.addPropView("cflag","编译参数",jsonObject.getString("cflag"));
			propListView.setOnPropChangedListener(this);
            contentView.setOrientation(LinearLayout.VERTICAL);
            contentView.setGravity(Gravity.CENTER_HORIZONTAL);
            logoView = new ImageView(MainActivity.this);
			int logoWidth = QMUIDisplayHelper.dp2px(MainActivity.this, 150);
            int logoMargin = QMUIDisplayHelper.dp2px(MainActivity.this, 10);
            LinearLayoutCompat.LayoutParams logoParams = new LinearLayoutCompat.LayoutParams(logoWidth, logoWidth);
            logoParams.setMargins(logoMargin, logoMargin, logoMargin, 0);
            logoView.setLayoutParams(logoParams);
            contentView.addView(logoView);
            contentView.addView(propListView);
			LayoutInflater.from(MainActivity.this).inflate(R.layout.fm_project_type,contentView,true);
			AppCompatSpinner spinner = contentView.findViewById(R.id.spinner_project);
			spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){

					@Override
					public void onItemSelected(AdapterView<?> p1, View p2, int p3, long p4)
					{
						// TODO: Implement this method
						switch(p3){
							case 0:
								jsonObject.put("type","Console");
								break;
							case 1:
								jsonObject.put("type","NativeActivity");
								break;
							case 2:
								jsonObject.put("type","OpenGLES");
								break;
							case 3:
								jsonObject.put("type","SDL2");
								break;
						}
					}

					@Override
					public void onNothingSelected(AdapterView<?> p1)
					{
						// TODO: Implement this method
					}
				});
			if(jsonObject.getString("type").equals("Console"))
				spinner.setSelection(0,true);
			if(jsonObject.getString("type").equals("NativeActivity"))
				spinner.setSelection(1,true);
			if(jsonObject.getString("type").equals("OpenGLES"))
				spinner.setSelection(2,true);
			if(jsonObject.getString("type").equals("SDL2"))
				spinner.setSelection(3,true);
            presenter.openProject(file);

        }

        @Override
        public void save() {
            super.save();
            FileUtil.write(getFile(), jsonObject.toJSONString());

        }

        @Override
        public View getContentView() {
            propListView.setProp("name", jsonObject.getString("name"), false);
            propListView.setProp("note", jsonObject.getString("note"), false);
            propListView.setProp("version", jsonObject.getString("version"), false);
            File logoFile = new File(getFile().getParent(), "icon.png");
            if (logoFile.exists()) {
                logoView.setImageBitmap(BitmapFactory.decodeFile(logoFile.getPath()));
            } else {
                logoView.setImageResource(R.drawable.logo_blue_dark);
            }
            contentView.setBackgroundColor(Colors.tabSelectColor);
            return contentView;
        }

        
        public void onPropChanged(String name, String property, BasePropView propView) {
            jsonObject.put(name, property);
            save();
            updateProject();
        }

        private void updateProject() {
            presenter.updateProject(jsonObject.getString("name"),
									jsonObject.getString("cflag"),
									jsonObject.getString("libs"),
									jsonObject.getString("type"));
        }
    }

    class ConfigType implements FileType {
        @Override
        public boolean forFile(File file) {
            return file.getPath().endsWith("config.json");
        }

        @Override
        public FileTabView.FileTab open(File file) {

            return new ConfigTab(file);
        }
    }

    private void initFileTypes() {
        addFileType(new XmlFileType());
        addFileType(new ImageFileType());
        addFileType(new ConfigType());
    }

    //CaptureView captureView;
    //UiDesignTreeView uiDesignTreeView;


    public void setTitle(CharSequence title) {
        //tvTitle.setText(title);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        presenter.detachView();
    }

    protected void run() {
        save();
        presenter.runProject();
    }

    protected void compile() {
        save();
        presenter.compileProject();

	}
    
	protected void save() {
        fileTabView.save();
    }
    public void refreshFile() {
        fileView.refreshFile();
    }
	/**
     * 检查是否打开文件，没有打开则显示文件列表
     */
    private void checkNotOpen() {
        if (fileTabView.getTabCount() == 0) {
            getDrawer().openDrawer(GravityCompat.END);
        }
    }
	
	ViewSwitcher viewSwitch;
	Toolbar toolbar ;
	FileView fileView;
	FileTabView fileTabView;
	ViewFlipper bottomPanel;
	ImageView quickKeyBarCloseButton;
	FloatingActionButton fab;
	DrawerLayout drawer;
    LinearLayout editorContentView;
	CodeEditText codeEditText;
	protected List<FileType> fileTypes;
	LinearLayout quickKeyBar;
	EditToolView editToolView;
	CodePresenter presenter;
    @Override
    public void onCreate(Bundle savedInstanceState)
	{
        super.onCreate(savedInstanceState);
		Colors.init(this);
        setContentView(R.layout.activity_main);
		InitTerminalUI();
		InitService();
		InitUI();
		InitEvent();
		initFileTypes();
	}
	void InitUI()
	{
		toolbar = (Toolbar) findViewById(R.id.toolbar);
		viewSwitch = (ViewSwitcher) findViewById(R.id.action_bar_switcher);
        setSupportActionBar(toolbar);
		fileView = (FileView) findViewById(R.id.fileView);
        fab = (FloatingActionButton) findViewById(R.id.fab);
		fab.setVisibility(View.GONE);
        bottomPanel = (ViewFlipper) findViewById(R.id.bottom_panel);
		quickKeyBarCloseButton = (ImageView) findViewById(R.id.quickKeyBarCloseButton);
        drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        //ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
		//	this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        //drawer.setDrawerListener(toggle);
        //toggle.syncState();
		fileTabView = (FileTabView) findViewById(R.id.file_tab);
		
		editorContentView = (LinearLayout) findViewById(R.id.layout_editor);
		quickKeyBar = (LinearLayout) findViewById(R.id.quickKeyBarLayout);
		editToolView = (EditToolView) findViewById(R.id.tool_view);
		presenter = new CodePresenter();
		presenter.attachView(this);
		presenter.openProject();
		
	}
	public void InitEvent(){
		final TranslateAnimation mShowAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,     
																Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,     
																-1.0f, Animation.RELATIVE_TO_SELF, 0.0f);     
		mShowAction.setDuration(500); 
		final TranslateAnimation mHiddenAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,     
											   0.0f, Animation.RELATIVE_TO_SELF, 0.0f,     
											   Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,     
											   -1.0f);    
		mHiddenAction.setDuration(500);   
		quickKeyBarCloseButton.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View p1)
				{
					// TODO: Implement this method
					quickKeyBar.startAnimation(mHiddenAction);
					fab.startAnimation(mShowAction);
					quickKeyBar.setVisibility(View.GONE);
					
					fab.setVisibility(View.VISIBLE);
				}
			});
		fab.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View p1)
				{
					// TODO: Implement this method
					fab.startAnimation(mHiddenAction);
					quickKeyBar.startAnimation(mShowAction);
					quickKeyBar.setVisibility(View.VISIBLE);
					
					fab.setVisibility(View.GONE);
				}
			});
		fileView.setFileListener(new FileView.FileListener() {
				@Override
				public void onDelete(final File file) {
					runOnUiThread(new Runnable() {
							@Override
							public void run() {
								//删除文件的时候，关闭tab
								fileTabView.closeTab(file);
							}
						});

				}

				@Override
				public void onAdd(File file) {

				}

				@Override
				public void onRename(final File oldFile, final File newFile) {
					runOnUiThread(new Runnable() {
							@Override
							public void run() {
								//重命名文件的时候，更新tab标题
								EditTab tab = (EditTab) fileTabView.findTab(oldFile);
								if (tab != null) {
									tab.file = newFile;
									tab.setTitle(newFile.getName() + (tab.changed ? "*" : ""));
								}
							}
						});

				}

				@Override
				public void onCut(final File oldFile, final File newFile) {
					runOnUiThread(new Runnable() {
							@Override
							public void run() {
								//剪切文件的时候，更新tab标题
								EditTab tab = (EditTab) fileTabView.findTab(oldFile);
								if (tab != null) {
									tab.file = newFile;
									tab.setTitle(newFile.getName() + (tab.changed ? "*" : ""));
								}
							}
						});
				}

				/**
				 * 打开文件的时候，关闭列表
				 * @param file
				 */
				@Override
				public void onOpen(File file) {
					try {
						openFile(file);
					} catch (Exception e) {
						Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
					}
					getDrawer().closeDrawers();
				}
			});
	}
	public interface FileType {
        boolean forFile(File file);

        FileTabView.FileTab open(File file);
    }
	/**
     * 打开文件，编辑文件
     *
     * @param file
     */
    public void openFile(File file) throws Exception {
        if (file == null || !file.exists()) {
            return;
        }
        if (fileTypes != null) {
            for (FileType fileType : fileTypes) {
                if (fileType.forFile(file)) {
                    FileTabView.FileTab open = fileType.open(file);
                    fileTabView.selectTab(fileTabView.addTab(open));
                    return;
                }
            }
        }
        fileTabView.selectTab(fileTabView.addTab(new EditTab(file)));
    }

    public void setProjectDir(File file) {
        fileView.setProjectFile(file);

    }

	@Override
	protected void onPause()
	{
		// TODO: Implement this method
		fileTabView.save();
		super.onPause();
	}
	
	/**
     * 隐藏代码提示
     */
    public void hideTips() {
		Logger.d("hid tips");
        if (codeEditText != null) {
            codeEditText.closeTips();
        }
    }
	/**
     * 拦截事件，隐藏提示
     *
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        hideTips();
        return super.dispatchTouchEvent(ev);
    }
	
    @Override
    public void onBackPressed()
	{
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
		DrawerLayout termuxDrawer = (DrawerLayout) findViewById(R.id.termux_drawer);
		getCurrentTermSession().isRunning();
        if (drawer.isDrawerOpen(GravityCompat.START))
		{
            drawer.closeDrawer(GravityCompat.START);
        }
		else if (termuxDrawer.isDrawerOpen(GravityCompat.END))
		{
            termuxDrawer.closeDrawer(GravityCompat.END);
        }
		else if (viewSwitch.getDisplayedChild() == 1)
		{
			viewSwitch.setDisplayedChild(0);
		}
		else
		{
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
	{
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }



    @Override
    public boolean onOptionsItemSelected(MenuItem item)
	{
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings)
		{
	        return true;
        }
		if (id == R.id.open_terminal)
		{
			if (viewSwitch.getDisplayedChild() == 1)
				viewSwitch.setDisplayedChild(0);
			else
			{
				viewSwitch.setDisplayedChild(1);
				if (mTermService.getSessions().isEmpty())
				{
					addNewSession(false,null);
				}
				mTerminalView.requestFocus();
			}
				
      		return true;
		}
		if (id == R.id.sav_all)
			save();
		if (id == R.id.action_compile)
			compile();
		if (id == R.id.action_run)
			run();
        return super.onOptionsItemSelected(item);
    }

	@Override
	public void removeFinishedSession(TerminalSession finishedSession)
	{
		// TODO: Implement this method
		if (mTermService.getSessions().isEmpty())
		{
			if (viewSwitch.getDisplayedChild() == 1)
				viewSwitch.setDisplayedChild(0);
			
			return;
		}
			
		super.removeFinishedSession(finishedSession);
	}
	
}

